<template>
  <div class="edit-menu">
    <a-modal
      :title="propsData.type === 'add' ? '新增角色' : '修改角色'"
      width="800px"
      :visible="visible"
      :confirm-loading="confirmLoading"
      :maskClosable="false"
      @ok="handleSubmit"
      @cancel="handleCancel"
    >
      <a-spin :spinning="spinning" tip="正在加载数据中...">
        <a-form :form="form" :label-col="{ span: 4 }" :wrapper-col="{ span: 18 }">
          <a-form-item label="角色名称">
            <a-input
              v-decorator="[
                'RoleName',
                { rules: [{ required: true, message: '请输入角色名称', trigger: 'change' }] }
              ]"
              placeholder="请输入角色名称"
              autocomplete="off"
              @change="changeRoleName"
            />
          </a-form-item>
          <!-- fix: 暂时弃用，保留 -->
          <!-- <a-form-item label="状态">
            <a-radio-group>
              <a-radio :value="1">正常</a-radio>
              <a-radio :value="2">停用</a-radio>
            </a-radio-group>
          </a-form-item> -->
          <a-form-item label="备注">
            <a-textarea
              v-decorator="['Remark', { initialValue: '' }]"
              :auto-size="{ minRows: 3, maxRows: 5 }"
              placeholder="请输入备注"></a-textarea>
          </a-form-item>
          <a-form-item label="菜单权限">
            <a-card :bodyStyle="{padding: '10px', height: '300px', overflowY: 'auto'}">
              <template v-if="treeData.length > 0">
                <!-- fix 2022-09-02 16:14 修改之前 新增属性 checkStrictly -->
                <a-tree
                  checkable
                  defaultExpandAll
                  :tree-data="treeData"
                  :checkedKeys="checkedKeys"
                  :replaceFields="{
                    title:'modulename',
                    key:'moduleid',
                    children:'children'
                  }"
                  @check="handleCheck"
                ></a-tree>
              </template>
              <template v-else>
                <a-empty />
              </template>
            </a-card>
          </a-form-item>
        </a-form>
      </a-spin>
    </a-modal>
  </div>
</template>

<script>
import moment from 'moment'
import debounce from 'lodash.debounce'
import { setRoles, getRoleTrees, getRoleInfo, queryRoleNames } from '@/api/system'
import cloneDeep from 'lodash.clonedeep'
export default {
  props: {
    visible: {
      type: Boolean,
      default: false
    },
    propsData: {
      type: Object,
      default: () => {
        return {}
      }
    }
  },
  data () {
    return {
      confirmLoading: false,
      spinning: false,
      treeData: [],
      form: this.$form.createForm(this, { name: 'editRole' }),
      checkNodeList: [],
      checkedKeys: []
    }
  },
  watch: {
    propsData: function (newVal) {
      this.fetchRole()
    }
  },
  methods: {
    fetchRole () {
      const { propsData: { id, type } } = this
      this.spinning = true
      const tree = new Promise((resolve, reject) => {
        getRoleTrees().then(res => {
          resolve(res.data)
        }).catch(() => {})
      })
      const info = new Promise((resolve, reject) => {
        if (type === 'update') {
          getRoleInfo({ roleID: id }).then(res => {
            resolve(res)
          })
        } else {
          resolve()
        }
      })
      Promise.all([tree, info]).then(res => {
        this.treeData = res[0]
        if (type === 'add') return
        const { data: { RoleName, Remark, modulelist } } = res[1]
        const checkedKeysList = this.compareItem(modulelist)
        this.$nextTick(function () {
          this.form.setFieldsValue({ RoleName, Remark })
          this.checkedKeys = checkedKeysList
          this.checkNodeList = checkedKeysList
        })
      }).catch(() => {
        this.$message.error('网络请求失败, 请稍后重试')
      }).finally(() => {
        this.spinning = false
      })
    },
    // 角色名称核验是否重复
    changeRoleName: debounce(function () {
      const { form: { validateFields, resetFields } } = this
      validateFields(['RoleName'], (errors, values) => {
        if (!errors) {
          const tips = this.$message.loading('正在核验当前输入角色名称是否存在...', 0)
          queryRoleNames({ RoleName: values.RoleName }).then(res => {
            if (res.code === 200) {
              setTimeout(tips, 500)
              setTimeout(() => {
                this.$message.success('核验通过')
              }, 1000)
            } else {
              setTimeout(tips, 500)
              setTimeout(() => {
                this.$message.error('核验不通过, 当前输入的角色名称已经存在')
              }, 1000)
              resetFields('RoleName')
            }
          }).catch((err) => {
            setTimeout(tips, 500)
            this.$message.error(err)
          })
        }
      })
    }, 1000, { leading: false }),
    handleCheck (checkedKeys, info) {
      this.checkedKeys = checkedKeys
      this.checkNodeList = checkedKeys.concat(info.halfCheckedKeys)
    },
    // 树形数据转扁平化数据
    getTreeChildren (treeList) {
      const result = []
      treeList && treeList.map(item => {
        if (item.children && item.children.length > 0) {
          result.push(...this.getTreeChildren(item.children))
        }
        result.push(item)
      })
      return result
    },
    // 构造处理提交时菜单权限列表
    structureNode (node) {
      const { getTreeChildren, treeData } = this
      const res = []
      const trees = getTreeChildren(cloneDeep(treeData))
      const childs = []
      for (var i in trees) {
        for (var k in node) {
          if (node[k] === trees[i].moduleid) {
            if (trees[i].children !== null || trees[i].moduleroot === '') {
              res.push({
                moduleid: trees[i].moduleid,
                modulename: trees[i].modulename,
                moduleroot: ''
              })
            } else {
              childs.push(trees[i])
            }
          }
        }
      }
      res.forEach(i => {
        const temp = []
        childs.forEach(j => {
          if (i.moduleid === j.pid && j.moduleroot !== '') {
            temp.push(j.modulekey)
          }
          i.moduleroot = temp.join()
        })
        return i
      })
      return res
    },
    // 获取角色信息时，回显菜单权限
    compareItem (list) {
      const result = []
      const checkData = this.getTreeChildren(list)
      for (let i = 0; i < checkData.length; i++) {
        if (checkData[i].isCheck === '1' && checkData[i].children === null) {
          result.push(checkData[i].moduleid)
        }
      }
      return result
    },
    handleSubmit () {
      const { form: { validateFields }, propsData: { type, id }, $message, checkNodeList } = this
      validateFields((errors, values) => {
        if (!errors) {
          this.confirmLoading = true
          let LastAlterTime = ''
          let ID = ''
          if (type === 'update') {
            LastAlterTime = moment(new Date()).format('YYYY-MM-DD HH:mm:ss')
            values.CreateTime = ''
            ID = id
          } else {
            values.CreateTime = moment(new Date()).format('YYYY-MM-DD HH:mm:ss')
          }
          setRoles({
            State: type,
            sys_role_Modules: Object.assign({}, values, {
              ID,
              CreateUserID: this.$store.getters.userid,
              CreateUserName: this.$store.getters.name,
              LastAlterTime,
              modulelist: this.structureNode(checkNodeList)
            })
          }).then((res) => {
            this.confirmLoading = false
            if (res.code === 200) {
              $message.success('提交成功', 3)
              this.handleCancel()
              this.$parent.$parent.$refs.table.refresh(true)
            } else {
              $message.error(res.msg, 3)
            }
          }).catch(() => {
            $message.error('提交失败', 3)
          })
        }
      })
    },
    handleCancel () {
      this.form.resetFields()
      this.treeData = []
      this.checkNodeList = []
      this.checkedKeys = []
      this.$emit('update:visible', false)
    }
  }
}
</script>
